/* 路由处理工具 */
import { cloneDeep } from 'lodash-es'
import { RouteRecordRaw } from 'vue-router'

/**
 * 将多级路由处理成两级路由
 * @param { Array<RouteRecordRaw> } routeModules 路由模块
 */
export function flatMultiLevelRoutes (routeModules: Array<RouteRecordRaw>) {
  const modules = cloneDeep(routeModules)
  modules.forEach((item) => {
    if (isMultilayerRoute(item)) {
      item.children = promoteRouteLevel(item.children as Array<RouteRecordRaw>, item.path)
    }
  })
  return modules
}

// 判读路由层级是否大于2层
function isMultilayerRoute (routes:RouteRecordRaw) {
  if (!routes || !routes.children || routes.children.length === 0) {
    return false
  }

  return routes.children.some((item) => item.children && item.children.length > 0)
}

// 递归路由 将树型数据改为同层数据
function promoteRouteLevel (routes: Array<RouteRecordRaw>, parentPath:string) {
  let arr: Array<RouteRecordRaw> = []
  routes.forEach((item) => {
    const isRoot = /^\//.test(item.path)
    if (parentPath && !isRoot) {
      // path 不以 '/' 开头
      item.path = `${parentPath}/${item.path}`
    }

    arr.push(item)

    if (item.component(true) === 'INHERIT_LAYOUT') {
      const children = item.children
      if (children && children.length > 0) {
        arr = arr.concat(promoteRouteLevel(children, item.path))
        // 释放 children 字段
        item.children = undefined
      }
    }
  })
  return arr
}

/**
 * 过滤路由
 * 通过用户角色过滤用户可访问的权限路由
 * @param { Array } routeModules 需要过滤的路由表
 * @param { Array } roles 角色列表
 */
export function filterRoutes (routeModules: Array<RouteRecordRaw>, roles: Array<string>) {
  const permissRoutes:Array<RouteRecordRaw> = []

  routeModules.forEach((route) => {
    if (checkPermission(route, roles)) {
      if (route.children) {
        route.children = filterRoutes(route.children, roles)
      }
      permissRoutes.push(route)
    }
  })
  return permissRoutes
}

/**
 * 检测权限
 * @param { Object } route 当前路由对象
 * @param { Array } roleList 角色列表
 */
function checkPermission (route: RouteRecordRaw, roleList: Array<string>) {
  const { meta } = route
  const { roles } = meta || {}

  if (roles) {
    return roleList.some((role) => roles.includes(role))
  } else {
    return true
  }
}
